//$Id: TileManager.java 239 2010-11-08 11:48:27Z edwardchuajh $

package builders;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;

/**
 * this class will manage all the tiles in the game
 * 
 * @author Vincent
 */
public class TileManager {

	public static final int HOMEBASE1 = 0;
	public static final int HOMEBASE2 = 9;
	public static final int HOMEBASE3 = 18;
	public static final int HOMEBASE4 = 27;
	public static final int TOTAL_NUMBER_OF_TILES_IN_BOARD = 36;

	private static final int TOTAL_NUMBER_OF_RANDOM_TILES = 36;

	private Tile[] tiles = new Tile[TOTAL_NUMBER_OF_TILES_IN_BOARD];
	private static String curDir = System.getProperty("user.dir");

	/**
	 * This is the default constructor of the TileManager class.
	 */
	public TileManager() {
		TileManagerRandom("templateForRandomTiles.txt");
	}

	/**
	 * This is the constructor of the TileManager class which allows the user to specify the file name from which the TileManager will load the data of the tiles.
	 * 
	 * the format of the .txt file is as follows:
	 * -for Tile
	 * tile number,
	 * multiplier,
	 * resource,
	 * tile description,
	 * name of tile,
	 * image file name,
	 * 
	 * -for HomeBase
	 * tile number,
	 * tile description,
	 * name of tile,
	 * image file name,
	 */ 
	public TileManager(String fileName) {
		TileManagerNormal(fileName);
	}

	/**
	 * @param fileName	specify the name of the file from which the TileManager will load the data of the tiles 
	 */
	private void TileManagerNormal(String fileName) {

		try {
			FileReader fileReader = new FileReader(curDir + "\\src\\builders\\" + fileName); 
			BufferedReader reader = new BufferedReader(fileReader);

			String tileNumber = null;

			while (!(tileNumber = reader.readLine()).equals("end of file")){

				int tileInt = Integer.valueOf(tileNumber);

				if (!isHomeBase(tileInt)) {

					String multiplier = reader.readLine(); 
					String resource = reader.readLine();
					String tileDescription = reader.readLine();
					String nameOfTile = reader.readLine();
					String imageFile = reader.readLine();

					Tile newTile = new Tile(multiplier, resource, tileDescription, nameOfTile, imageFile);

					tiles[tileInt] = newTile;
				} else {

					String tileDescription = reader.readLine();
					String nameOfTile = reader.readLine();
					String imageFile = reader.readLine();

					HomeBase newHomeBase = new HomeBase(tileDescription, nameOfTile, imageFile);
					tiles[tileInt] = newHomeBase;
				}
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (NumberFormatException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * @param fileName	specify the file from which the data will be read and put randomly into the TileManager
	 */
	private void TileManagerRandom(String fileName) {

		try {
			FileReader fileReader = new FileReader(curDir + "\\src\\builders\\" + fileName); 
			BufferedReader reader = new BufferedReader(fileReader);
			Tile[] forRandomData = new Tile[TOTAL_NUMBER_OF_RANDOM_TILES];
			ArrayList<Integer> usedTile = new ArrayList<Integer>(); 

			for (int randomTile = 0; randomTile < TOTAL_NUMBER_OF_RANDOM_TILES; randomTile++){
				String multiplier = reader.readLine(); 
				String resource = reader.readLine();
				String tileDescription = reader.readLine();
				String nameOfTile = reader.readLine();
				String imageFile = reader.readLine();
				Tile newRandomTile = new Tile(multiplier, resource, tileDescription, nameOfTile, imageFile);
				forRandomData[randomTile] = newRandomTile;
			}

			for (int tileNumber = 0; tileNumber < TOTAL_NUMBER_OF_TILES_IN_BOARD; tileNumber++){

				if (!isHomeBase(tileNumber)) {
					Random r = new java.util.Random();
					int rand = r.nextInt(TOTAL_NUMBER_OF_RANDOM_TILES);

					while (usedTile.contains(rand)){
						rand = (rand + r.nextInt(7) + TOTAL_NUMBER_OF_RANDOM_TILES) % TOTAL_NUMBER_OF_RANDOM_TILES;
					}
					usedTile.add(rand);

					tiles[tileNumber] = forRandomData[rand];

				} else {

					String tileDescription = reader.readLine();
					String nameOfTile = reader.readLine();
					String imageFile = reader.readLine();

					HomeBase newHomeBase = new HomeBase(tileDescription, nameOfTile, imageFile);
					tiles[tileNumber] = newHomeBase;
				}
			}

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * this is used to check if the number given corresponds to a homeBase 
	 * 
	 * @param tileNumber	the number that will be checked to see if it corresponds to a homeBase number
	 * @return				true if the input number corresponds to a homeBase number, otherwise false
	 */
	private boolean isHomeBase(int tileNumber) {
		return tileNumber == HOMEBASE1 || tileNumber == HOMEBASE2 || tileNumber == HOMEBASE3 || tileNumber == HOMEBASE4;
	}

	/**
	 * this is called to retrieve the tile based on a number
	 * 
	 * @param square	the number that will be used to get the tile which the number corresponds to
	 * @return			the tile which the input number corresponds to
	 */
	public Tile squareToTile(int square) {
		return tiles[square];
	}

	/**
	 * @return	the array of tiles managed by TileManager
	 */
	public Tile[] getTiles(){
		return tiles;
	}

	/**
	 * @return	a String which contains the data and the arrangement of all the tiles currently in the TileManager
	 */
	public String getTilesData(){
		String data = "";
		for(int tileNumber = 0; tileNumber < TOTAL_NUMBER_OF_TILES_IN_BOARD; tileNumber++){
			if (!isHomeBase(tileNumber)) {

				data += (tiles[tileNumber].getMultiplier() + ",");
				data += (tiles[tileNumber].getResource().toString() + ",");
				data += (tiles[tileNumber].getTileDescription() + ",");
				data += (tiles[tileNumber].getNameOfTile() + ",");
				data += (tiles[tileNumber].getImageFile() + ",");
			} else {
				data += (tiles[tileNumber].getTileDescription() + ",");
				data += (tiles[tileNumber].getNameOfTile() + ",");
				data += (tiles[tileNumber].getImageFile() + ",");
			}
		}
		return data;
	}

	/**
	 * @param data	specify the data to be loaded into TileManager
	 */
	public void makeTiles(String data){
		loadData(data.split(","));
	}

	/**
	 * @param data	specify the data to be loaded into TileManager
	 */
	private void loadData(String[] data) {

		// load data from input to TileManager
		int pointer = 0; 
		for (int tileNumber = 0; tileNumber < TOTAL_NUMBER_OF_TILES_IN_BOARD; tileNumber++) {
			if (!isHomeBase(tileNumber)) {

				String multiplier = data[pointer++];
				String resource = data[pointer++];
				String tileDescription = data[pointer++];
				String nameOfTile = data[pointer++];
				String imageFile = data[pointer++];

				Tile newTile = new Tile(multiplier, resource, tileDescription, nameOfTile, imageFile);
				tiles[tileNumber] = newTile;
			} else {
				String tileDescription = data[pointer++];
				String nameOfTile = data[pointer++];
				String imageFile = data[pointer++];

				HomeBase newHomeBase = new HomeBase(tileDescription, nameOfTile, imageFile);
				tiles[tileNumber] = newHomeBase;
			}
		}
	}
}